package org.jpass.dc.business.project.logic;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
/**
 * 压缩
 * @author Administrator
 *
 */
public class ZipService {
	
	private  static final int BUFFER  = 1024; // 缓冲字节数
	
	public void compress(String srcFilePath, String zipFilePath) throws IOException {
		File srcFile = new File(srcFilePath);
		if(!srcFile.exists()) throw new FileNotFoundException();
		
		FileOutputStream fos = new FileOutputStream(new File(zipFilePath));
		CheckedOutputStream cos = 
			new CheckedOutputStream(fos, new CRC32()); // 显示指定计算和校验文件的校验和的方法，有两种Checksun类型：Adler32（慢一些）和CRC32（快一些）
		ZipOutputStream zos = new ZipOutputStream(cos);
		zos.setEncoding("gb2312"); // 设置压缩的时候文件名编码为gb2312, 防止压缩文件时出现文件名中文乱码
		String basedir = ""; // 保持文件压缩后的目录结构
		compress(basedir, srcFile, zos);
		zos.close();
		fos.close();
	}
	
	public void compress(String basedir, File file, ZipOutputStream zos) throws IOException {
		if (file.isDirectory()) {
			compressDirectory(basedir, file, zos);
		} else {
			compressFile(basedir, file, zos);
		}
	}
	
	/**
	 * 遍历文件夹下面的文件，并打包
	 * @param dir
	 * @param zos
	 * @throws IOException
	 */
	private void compressDirectory(String basedir, File dir, ZipOutputStream zos) throws IOException {
		if (!dir.exists()) return;
		
		File files[] = dir.listFiles();
		for (int i = 0, len = files.length; i < len; i++) {
			compress(basedir + dir.getName() + "/", files[i], zos); // 递归遍历子文件
		}
	}
	
	/**
	 * 打包文件
	 * @param file
	 * @param zos
	 * @throws IOException
	 */
	private void compressFile(String basedir, File file, ZipOutputStream zos) throws IOException {
		if (!file.exists()) return;
		
		BufferedInputStream bis = new BufferedInputStream(
			     new FileInputStream(file));
		zos.putNextEntry(new ZipEntry(basedir + file.getName()));
		int len = 0;
		byte data[] = new byte[BUFFER];
		while((len = bis.read(data, 0, BUFFER)) != -1) {
			zos.write(data, 0, len);
		}
		zos.closeEntry();
		bis.close();
	}
}
